package db

import (
	"code.google.com/p/jesus-1496/serverlog"
	"code.google.com/p/jesus-1496/settings"
	"database/sql"
	"encoding/json"
	"fmt"
	_ "github.com/lib/pq"
	"time"
)

var logger = serverlog.NewServerLog("db")
var db *sql.DB = nil

func init() {
	connString := fmt.Sprintf(
		"user=%s dbname=%s address=%s port=%d password=%s sslmode=require",
		settings.Settings.Db.Username,
		settings.Settings.Db.DbName,
		settings.Settings.Db.Address,
		settings.Settings.Db.Port,
		settings.Settings.Db.Password)
	logger.Printf("Attempting to connect to database with connection string: %s", connString)
	d, err := sql.Open("postgres", connString)
	if err != nil {
		panic(err.Error())
	}
	db = d
	logger.Printf("Connected to database.")
	go auditDb(db)
}

func Db() *sql.DB {
	return db
}

func auditDb(d *sql.DB) {
	ticker := time.Tick(time.Minute * 5)
	for _ = range ticker {
		logger.Printf("Pinging database...")
		err := db.Ping()
		if err != nil {
			logger.Printf("Error during ping: %v.", err)
		} else {
			logger.Printf("Ping successful.")
		}
	}
}

func UnmarshallQuery(v interface{}, query string, args ...interface{}) error {

	var resultString string
	row := db.QueryRow(query, args...)
	if row == nil {
		return fmt.Errorf("UnmarshallQuery: nil row received. Query:%s, args: %v.", query, args)
	}

	err := row.Scan(&resultString)
	if err != nil {
		return fmt.Errorf("UnmarshallQuery: error during row scan. Query:%s, args: %v, resultString:%s. Error:%v", query, args, resultString, err)
	}

	err = json.Unmarshal([]byte(resultString), v)
	if err != nil {
		return fmt.Errorf("UnmarshallQuery: error during unmarshall. Query:%s, args: %v. Error: %v", query, args, err)
	}
	return nil
}

func Exec(query string, args ...interface{}) (sql.Result, error) {
	return db.Exec(query, args...)
}
